package com.towker;

import java.io.File;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.http.HttpServletRequest;

import com.towker.core.util.GetPath;


public class FileuploadFactory extends Thread
{
	private Timer _timer = null;
	private static int count = 0;
	private static Map<Long, Long> fileuploadSessionMap = new HashMap<Long, Long>();
	private static synchronized int getCount() {return FileuploadFactory.count;}
	private static synchronized void setCount(int count) {FileuploadFactory.count = count;}
	static//临时目录初始化，在服务器启动时执行
	{
		try
		{
			String str=FileuploadFactory.class.getResource("FileuploadFactory.class").getPath(); 
			str=str.substring(1, str.indexOf("WEB-INF/classes"));//从路径字符串中取出工程路径
			String path =str + ParamFactory.FILEUPLOAD_SAVEPATH;
			if(!(path.substring(path.length()-1)).equals(File.separatorChar))
			{
				path = path + File.separatorChar;
			}
			java.io.File f = new java.io.File(path);
			System.out.println(f.getPath());
			FileuploadFactory.delete(f);//删除整个目录
		}
		catch(Exception ex)
		{
		}
	}
	//判断Map是否有值存在
	private static synchronized boolean existMapValue()
	{
		//if(FileuploadFactory.fileuploadSessionMap == null)
		//	FileuploadFactory.fileuploadSessionMap = new HashMap<Long, Long>();
		if(FileuploadFactory.fileuploadSessionMap.size() > 0)
			return true;
		return false;
	}
	//删除文件夹或文件
	private static boolean delete(File file)
	{
		try
		{
			if(file.isDirectory())
			{
				String[] children = file.list();
				for(int i = 0; i < children.length; i++)
				{
					FileuploadFactory.delete(new File(file, children[i]));
				}
			}
			return file.delete();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
			return false;
		}
	}
	//移除fileuploadSession
	private static synchronized void removeFileuploadSession(long fileuploadSession)
	{
		try
		{
			FileuploadFactory.fileuploadSessionMap.remove(fileuploadSession);//移除标识
		}
		catch(Exception ex)
		{
		}
	}

	/**
	 * 删除整个临时上传目录
	 * @param fileuploadSession
	 * @return
	 */
	public static boolean delFileuploadSession(long fileuploadSession)
	{
		try
		{
			if(fileuploadSession <= 0)
				return false;
			String str=FileuploadFactory.class.getResource("FileuploadFactory.class").getPath(); 
			str=str.substring(1, str.indexOf("WEB-INF/classes"));//从路径字符串中取出工程路径
			String path =str + ParamFactory.FILEUPLOAD_SAVEPATH;
			path = path + File.separatorChar;
			path = path + fileuploadSession + File.separatorChar;
			java.io.File f = new java.io.File(path);
			FileuploadFactory.delete(f);//删除整个目录
			FileuploadFactory.removeFileuploadSession(fileuploadSession);//移除标识
			return true;
		}
		catch(Exception ex)
		{
			FileuploadFactory.removeFileuploadSession(fileuploadSession);//移除标识
		}
		return false;
	}

	public void run()
	{
		if(FileuploadFactory.getCount() != 0)//启动中
		{
			return;
		}
		if(!FileuploadFactory.existMapValue())
		{
			return;//同样不需要启动
		}
		FileuploadFactory.setCount(1);//标记启动
		try
		{
			TimerTask _timerTask = new TimerTask()
			{
				public void run()
				{
					try
					{
						if(FileuploadFactory.existMapValue())
						{
							long currTime = Calendar.getInstance().getTimeInMillis();//取得当前时间
							for(Map.Entry<Long, Long> entry: FileuploadFactory.fileuploadSessionMap.entrySet())
							{
								if(currTime - entry.getValue().longValue() > ParamFactory.FILEUPLOAD_UPLOADTIMEOUT)
								{
									FileuploadFactory.delFileuploadSession(entry.getKey());//超时,移除
								}
							}
						}
						if(!FileuploadFactory.existMapValue())
						{
							_timer.cancel();
							FileuploadFactory.setCount(0);
							System.out.println("--临时上传目录清理程序结束，清理完毕。--");
						}
					}
					catch(Exception ex)
					{
						_timer.cancel();
						FileuploadFactory.setCount(0);
						System.out.println("--临时上传目录清理程序异常结束。--");
					}
				}
			};
			_timer = new Timer(true);
			// Timer.schedule(TimerTask task, Date date, long period)// 从date开始,每period毫秒执行task.
			_timer.schedule(_timerTask, 0, ParamFactory.FILEUPLOAD_UPLOADTIMEOUT);// 从服务器启动开始运行,每period毫秒执行
			System.out.println("--临时上传目录清理程序启动，已经添加任务调度表，清理间隔" + ParamFactory.FILEUPLOAD_UPLOADTIMEOUT/1000 + "秒。--");
		}
		catch(Exception ex)
		{
			try {_timer.cancel();}catch(Exception timerEx) {}//尝试停止进程，即使它未初始化或未启动
			ex.printStackTrace();
			System.out.println("--临时上传目录清理程序异常结束。--");
			FileuploadFactory.setCount(0);
		}
	}

//################################################################################################
/*
 * 简单说明：fileuploadSession是一次会话对应的值,根据它生成一个fileuploadSession目录,该目录下有多个filenum目录,一个filenum对应一次上传提交
 * 1 调用getNewFileuploadSession()获取fileuploadSession
 * 2 getNewFileNum()同类文件上传表单所对应的编号，用于找到相应的文件[(一个公告下的多个附件可用同一个filenum),(一个人的头像、证件图片用不同的filenum)]
 * 3 上传前后调用toStart(),启动定时清理程序将生成的FileuploadSession目录加入清理队列
 * 4 在调用toStart后,可显示调用refreshFileuploadSession推迟已上传文件失效时间,未及时处理的文件在一定时间后会被删除,每调用一次可将删除时间推迟
 * 5 已处理的文件调用delFile进行删除,节约服务器空间
*/
//################################################################################################
	public static final String SessionName_UploadSessionNumber = "UPLOADSESSIONNUMBER";
	private static int fileNum = 0;
	private static long fileuploadSession = Calendar.getInstance().getTimeInMillis();
	/**
	 * 获取一个新的上传文件会话信息
	 * @return
	 */
	public static final synchronized long getNewFileuploadSession()
	{
		return fileuploadSession++;
	}
	/**
	 * 获取一个新的上传文件号码标识
	 * @return
	 */
	public static final synchronized int getNewFileNum()
	{
		if(FileuploadFactory.fileNum == Integer.MAX_VALUE)
			FileuploadFactory.fileNum = 0;//还原
		FileuploadFactory.fileNum++;//增加1
		return FileuploadFactory.fileNum;
	}
	/**
	 * 刷新fileuploadSession时间
	 * @param key
	 */
	public static synchronized void refreshFileuploadSession(long fileuploadSession)
	{
		try
		{
			FileuploadFactory.fileuploadSessionMap.put(fileuploadSession, Calendar.getInstance().getTimeInMillis());//更新时间标识
		}
		catch(Exception ex)
		{
		}
	}
	/**
	 * 根据参数取得上传的文件列表
	 * @param fileuploadSession
	 * @param fileNum
	 * @return
	 */
	public static File[] getFile(long fileuploadSession, int fileNum)
	{
		try
		{
			if(fileuploadSession <= 0 || fileNum <= 0)
				return null;
			String str=FileuploadFactory.class.getResource("FileuploadFactory.class").getPath(); 
			str=str.substring(1, str.indexOf("WEB-INF/classes"));//从路径字符串中取出工程路径
			String path =str + ParamFactory.FILEUPLOAD_SAVEPATH;
			if(!(path.substring(path.length()-1)).equals(File.separatorChar))
			{
				path = path + File.separatorChar;
			}
			path = path + fileuploadSession + File.separatorChar + fileNum + File.separatorChar;
			java.io.File f = new java.io.File(path);
			if(f.isDirectory())//正常情况下只会是文件夹或不存在，而不可能是文件
			{
				return f.listFiles();//正常情况下只会是文件列表，不会存在子文件夹
			}
			FileuploadFactory.delete(f);//不正常文件，直接删除
		}
		catch(Exception ex)
		{
		}
		return null;
	}
	/**
	 * 删除指定的文件
	 * @param fileuploadSession
	 * @param fileNum
	 * @return
	 */
	public static boolean delFile(long fileuploadSession, int fileNum)
	{
		try
		{
			if(fileuploadSession <= 0 || fileNum <= 0)
				return false;
			String str=FileuploadFactory.class.getResource("FileuploadFactory.class").getPath(); 
			str=str.substring(1, str.indexOf("WEB-INF/classes"));//从路径字符串中取出工程路径
			String path =str + ParamFactory.FILEUPLOAD_SAVEPATH;
			if(!(path.substring(path.length()-1)).equals(File.separatorChar))
			{
				path = path + File.separatorChar;
			}
			path = path + fileuploadSession + File.separatorChar + fileNum + File.separatorChar;
			java.io.File f = new java.io.File(path);
			FileuploadFactory.delete(f);//删除整个目录
			return true;
		}
		catch(Exception ex)
		{
		}
		return false;
	}
	/**
	 * 启动临时上传目录清理程序,在目录生成或文件上传后,才需要将fileuploadSession加入管理程序
	 */
	public static final synchronized void toStart(long fileuploadSession)
	{
		FileuploadFactory.refreshFileuploadSession(fileuploadSession);
		FileuploadFactory clearDao = new FileuploadFactory();
		clearDao.start();//启动临时上传目录清理程序
	}
	// ################################################################################################
	/*
	 * 上传参数获取方法,可以把两个方法移到Login类中
	 */
	// ################################################################################################
	/**
	 * 获取并刷新fileuploadSession值，没有则返回0，供FileuploadFactory作上传用：fileuploadSession
	 */
	public static final long getFileuploadSession(javax.servlet.http.HttpServletRequest request)
	{
		Object obj = String.valueOf(request.getSession().getAttribute(FileuploadFactory.SessionName_UploadSessionNumber));
		long key = 0L;
		if (obj != null)
		{
			try
			{
				key = Long.parseLong(String.valueOf(obj));
				if (key > 0)
				{
					FileuploadFactory.refreshFileuploadSession(key);
					request.getSession().setAttribute(FileuploadFactory.SessionName_UploadSessionNumber, key);
					return key;
				}
			}
			catch (NumberFormatException e)
			{
			}
		}
		request.getSession().setAttribute(FileuploadFactory.SessionName_UploadSessionNumber, null);
		return 0;
	}

	/**
	 * 获取并刷新fileuploadSession值，没有则新创建一个，供FileuploadFactory作上传用：fileuploadSession
	 * @param request
	 * @return
	 */
	public static final long refreshFileuploadSession(javax.servlet.http.HttpServletRequest request)
	{
		long key = FileuploadFactory.getFileuploadSession(request);
		if (key > 0)
		{
			return key;
		}
		key = FileuploadFactory.getNewFileuploadSession();
		request.getSession().setAttribute(FileuploadFactory.SessionName_UploadSessionNumber, key);
		FileuploadFactory.toStart(key);
		FileuploadFactory.refreshFileuploadSession(key);
		return key;
	}
	
//	public static String getWebPath()
//	{
//		String str=FileuploadFactory.class.getResource("FileuploadFactory.class").getPath(); 
//		str=str.substring(1, str.indexOf("WEB-INF/classes"));//从路径字符串中取出工程路径
//		return str;
//	}
}
